
class IcyPromiseObserver {
  constructor() {
    this._storage = {};
  }

  subscribe(event) {
    let _local = this._storage[event];

    return new Promise((resolve, reject) => {
      
      try {
        if (_local instanceof Array) {

          _local.push(resolve);

        } else {

          // undefined or other types -- initialize --> Array
          _local = [];
          _local.push(resolve);
        }
      } catch(err) {
        reject(err);
        throw new Error('subscribe failed');
      }
      
      return this._storage[event] = _local;
    })
  }

  publish(event, ...args) {
    let _local = this._storage[event];
    
    return new Promise((resolve, reject) => {

      try {
        for (let eachFun of _local) {
          eachFun(...args);
        }
        resolve();
      } catch (err) {
        reject(err);
        throw new Error('publish unregister message');
      }
    });
  }

  list() {
    console.log(this._storage);
  }
}

icy = new IcyPromiseObserver();

{
  let where = 'area a';
  icy
  .subscribe('message1')
  .then((e) => {
    console.log(`This is ${where} receiving ${e.from}`);
  });
  icy.list();
}
{
  let where = 'area b';
  icy
  .subscribe('message1')
  .then((e) => {
    console.log(`This is ${where} receiving ${e.from}`)
  });
  icy.list();
}
{
  icy.publish('message1', {
    'from': 'area c'
  });
}